package util

import (
	"crypto/md5"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"github.com/unknwon/com"
	"github.com/wenzhenxi/gorsa"
	"io/ioutil"
	"likeadmin/core"
	"net/http"
	"net/url"
	"sort"
	"strings"
)

// RsaEncrypt 使用RSA算法对数据进行加密
// 参数:
//
//	data: 需要加密的数据，类型为map[string]interface{}，用于存储各种数据
//	privateKey: 私钥字符串，用于加密数据
//
// 返回值:
//
//	加密后的数据，以base64编码的字符串形式返回
//	error: 错误信息，如果加密过程中发生错误
func RsaEncrypt(data map[string]interface{}, privateKey string) (string, error) {
	jsonData, _ := json.Marshal(data)

	gRsa := gorsa.RSASecurity{}
	if err := gRsa.SetPrivateKey("\n-----BEGIN PRIVATE KEY-----\n" + privateKey + "\n-----END PRIVATE KEY-----\n"); err != nil {
		return "", err
	}

	rsaData, err := gRsa.PriKeyENCTYPT(jsonData)
	if err != nil {
		return "", err
	}

	baseData := base64.StdEncoding.EncodeToString(rsaData)
	return baseData, nil
}

// RsaDecrypt 使用RSA算法对数据进行解密
// 参数:
//
//	data: 需要解密的数据，以base64编码的字符串形式输入
//	publicKey: 公钥字符串，用于解密数据
//
// 返回值:
//
//	解密后的数据，以字符串形式返回
//	error: 错误信息，如果解密过程中发生错误
func RsaDecrypt(data string, publicKey string) (string, error) {
	data = strings.Replace(data, "\\n", "", -1)
	data = strings.Replace(data, " ", "+", -1)
	dataBs, err := base64.RawStdEncoding.DecodeString(data)
	if err != nil {
		return "", err
	}

	gRsa := gorsa.RSASecurity{}
	if err := gRsa.SetPublicKey("\n-----BEGIN PUBLIC KEY-----\n" + publicKey + "\n-----END PUBLIC KEY-----\n"); err != nil {
		return "", err
	}

	rsaData, err := gRsa.PubKeyDECRYPT(dataBs)
	if err != nil {
		return "", err
	}

	return string(rsaData), nil
}

// mihuaPay 发起HTTP请求以进行支付操作
// 参数:
//
//	u: 请求的URL
//	data: 请求的数据，以字符串形式输入
//	method: HTTP方法，例如"POST"或"GET"
//
// 返回值:
//
//	响应的数据，以字节切片形式返回
func mihuaPay(u string, data string, method string) []byte {

	client := &http.Client{}
	req, err := http.NewRequest(method, u, strings.NewReader(data))
	if err != nil {
		core.Logger.Errorf("调用米花支付失败 err: err=[%+v]", err)
	}

	req.Header.Set("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")

	resp, err := client.Do(req)
	if err != nil {
		return nil
	}

	defer resp.Body.Close()

	body2, err := ioutil.ReadAll(resp.Body)

	if err != nil {
		core.Logger.Errorf("调用米花支付失败~ err: err=[%+v]", err)
	}

	return body2
}

// PaySend 准备支付数据并发送支付请求
// 参数:
//
//	p: 支付参数，类型为map[string]interface{}，用于存储支付所需的各项数据
//	prv: 私钥字符串，用于加密支付数据
//
// 返回值:
//
//	支付响应数据，类型为map[string]interface{}，包含支付结果的各项数据
func PaySend(p map[string]interface{}, prv, merAccount string) map[string]interface{} {

	sortP := FirstLetterSort(p)

	var sign string
	for _, value := range sortP {
		switch p[value].(type) {
		case string:
			sign += p[value].(string)
			break
		case int:
			sign += com.ToStr(p[value])
			break
		}
	}
	sign += prv

	p["sign"] = strings.ToTitle(Md5s(sign))

	fmt.Println("data:", p)
	aes, aesRrr := RsaEncrypt(p, prv)

	if aesRrr != nil {
		core.Logger.Errorf("PaySend~ err: err=[%+v]", aesRrr)
		return map[string]interface{}{}
	}

	url2 := "https://platform.mhxxkj.com/paygateway/mbpay/order/v1"
	var postFrom = url.Values{}
	postFrom.Add("data", aes)
	postFrom.Add("merAccount", merAccount)

	/*请求数据*/
	data1 := postFrom.Encode()

	d := mihuaPay(url2, data1, "POST")

	/*接收参数*/
	var returnString2 = make(map[string]interface{})

	jerr := json.Unmarshal(d, &returnString2)

	if jerr != nil {
		core.Logger.Errorf("PaySend~ jerr: err=[%+v]", jerr)
		return map[string]interface{}{}
	}

	return returnString2
}

func FirstLetterSort(data map[string]interface{}) []string {
	var sslice []string
	for key, _ := range data {
		sslice = append(sslice, key)
	}
	sort.Strings(sslice)

	return sslice
}

// Md5s 计算字符串的 MD5 哈希值。
// s: 输入字符串。
// 返回值:
// - string: MD5 哈希值的十六进制表示。
func Md5s(s string) string {
	r := md5.Sum([]byte(s))
	return hex.EncodeToString(r[:])
}
